package jdklearning.process;

import java.io.IOException;


/**
 *   1.  RunTime.getRuntime（）.exec（String  command）;
 *
 *                          在windows下相当于直接调用   /开始/搜索程序和文件  的指令，比如
 *                          Runtime.getRuntime().exec("notepad.exe");  -------打开windows下记事本。
 *
 *
 *  2. public Process exec(String [] cmdArray)；
 *    Linux下：
 *      Runtime.getRuntime().exec(new String[]{"/bin/sh","-c", ";
 *    Windows下：
 *      Runtime.getRuntime().exec(new String[]{ "cmd", "/c", cmds});
 *
 *
 * Process的几种方法：
 *                         1.destroy()：杀掉子进程
 *
 * 2.exitValue()：返回子进程的出口值，值 0 表示正常终止
 *
 * 3.getErrorStream()：获取子进程的错误流
 *
 * 4.getInputStream()：获取子进程的输入流
 *
 * 5.getOutputStream()：获取子进程的输出流
 *
 * 6.waitFor()：导致当前线程等待，如有必要，一直要等到由该 Process 对象表示的进程已经终止。如果已终止该子进程，此方法立即返回。如果没有终止该子进程，调用的线程将被阻塞，直到退出子进程，根据惯例，0 表示正常终止
 *
 *
 *  注意：在java中，调用runtime线程执行脚本是非常消耗资源的，所以切忌不要频繁使用！
 *
 *                     在调用runtime去执行脚本的时候，其实就是JVM开了一个子线程去调用JVM所在系统的命令，其中开了三个通道： 输入流、输出流、错误流，其中输出流就是子线程走调用的通道。
 *                     大家都知道，waitFor是等待子线程执行命令结束后才执行， 但是在runtime中，打开程序的命令如果不关闭，就不算子线程结束。比如以下代码。
 *                          代码：private static Process p = null;
 *                                             p = Runtime.getRuntime().exec("notepad.exe");
 *     p.waitFor();
 * System.out.println("--------------------------------------------我被执行了");
 *                      以上代码中，打开windows中记事本。如果我们不手动关闭记事本，那么输出语句就不会被执行，这点是需要理解的。
 *
 *   process的阻塞：
 *                       在runtime执行大点的命令中，输入流和错误流会不断有流进入存储在JVM的缓冲区中，如果缓冲区的流不被读取被填满时，就会造成runtime的阻塞。所以在进行比如：大文件复制等的操作时，我们还需要不断的去读取JVM中的缓冲区的流，来防止Runtime的死锁阻塞。
 *
 * @author shenenlu 2021年06月23日 上午10:00:34
 *
 * https://www.cnblogs.com/tohxyblog/p/6501396.html
 */
public class ShellLearning {

    public static void main(String[] args) throws IOException, InterruptedException {
        Process shell = Runtime.getRuntime().exec("notepad.exe");

        //0 表示正常终止
        int i = shell.waitFor();
        System.out.println("waitFor:"+i);
    }

}
